<?php 
pake_desc('Create an "Hello world" OpenSocial application');
pake_task('init-opensocial-app', 'project_exists');

function loadOpensocialAppDirs($rootDir)
{
  $sfPluginsDir = sfConfig::get('sf_plugins_dir');
  $opensocialPluginDir = $sfPluginsDir.DIRECTORY_SEPARATOR.'sfOpenSocialPlugin';
  
  if(!is_dir($opensocialPluginDir))
    throw new Exception("sfOpenSocialPlugin is not proper installed (it should be located in '$opensocialPluginDir'");
  return $opensocialPluginDir.DIRECTORY_SEPARATOR.'misc'.DIRECTORY_SEPARATOR.'app';
}

function loadOpensocialAppModuleDirs($rootDir)
{
  $sfPluginsDir = sfConfig::get('sf_plugins_dir');
  $opensocialPluginDir = $sfPluginsDir.DIRECTORY_SEPARATOR.'sfOpenSocialPlugin';
  
  if(!is_dir($opensocialPluginDir))
    throw new Exception("sfOpenSocialPlugin is not proper installed (it should be located in '$opensocialPluginDir'");
  return $opensocialPluginDir.DIRECTORY_SEPARATOR.'misc'.DIRECTORY_SEPARATOR.'module';
}

function writeToFile($file, $data)
{           
	if(is_writable($file))
	{
		$fp = fopen($file, "w");
		fwrite($fp, $data);
		fclose($fp);   
	}
	else
	{
    $errorText .= "Can not replace text. File $file is not writable. \nPlease make it writable\n";   
	}
}

function fixModuleNames($moduleDir,$moduleName)
{
	$pattern = 'class opensocial';
	
	// open actions.class.php file from the moduleDir
	$actionsFile = $moduleDir.DIRECTORY_SEPARATOR.sfConfig::get('sf_app_module_action_dir_name').DIRECTORY_SEPARATOR.'actions.class.php';
	$actionsContent = file_get_contents($actionsFile); 
	// finds the string 'class opensocial' and replaces by 'class $moduleName'
	$outputStr = str_ireplace($pattern, 'class '.$moduleName, $actionsContent);
	// writes the new content to the file
	writeToFile($actionsFile,$outputStr);
  
	// open components.class.php file from the moduleDir
  $componentsFile = $moduleDir.DIRECTORY_SEPARATOR.sfConfig::get('sf_app_module_action_dir_name').DIRECTORY_SEPARATOR.'components.class.php';
  $componentsContent = file_get_contents($componentsFile); 
  // finds the string 'class opensocial' and replaces by 'class $moduleName'
  $outputStr = str_ireplace($pattern, 'class '.$moduleName, $componentsContent);
  // writes the new content to the file
  writeToFile($componentsFile,$outputStr);
  
  $pattern = "include_component('opensocial',";
  $templatesFile = $moduleDir.DIRECTORY_SEPARATOR.sfConfig::get('sf_app_module_template_dir_name').DIRECTORY_SEPARATOR.'indexSuccess.php';
  $templatesContent = file_get_contents($templatesFile); 
  $outputStr = str_ireplace($pattern, "include_component('$moduleName',", $templatesContent);
  writeToFile($templatesFile,$outputStr);
}

function enable_sampleapp($applicationDir,$sampleAppName)
{
	$settingsFile = $applicationDir.DIRECTORY_SEPARATOR.sfConfig::get('sf_app_config_dir_name').DIRECTORY_SEPARATOR.'settings.yml';
	$settingsContent = file_get_contents($settingsFile); 
	
	$outputStr = str_ireplace('#all:', 'all:', $settingsContent);
  $outputStr = str_ireplace('#  .settings:', '  .settings:', $outputStr);
  $outputStr = str_ireplace('#    enabled_modules:', '    enabled_modules:', $outputStr);
  $outputStr = str_ireplace('    enabled_modules:        [default', '    enabled_modules:        [default, '.$sampleAppName, $outputStr);
  
  writeToFile($settingsFile,$outputStr);
}

function run_init_opensocial_app($task, $args)
{
  if( count($args) < 2 )
  {
    throw new Exception("You must enter your application name and module.\nUsage:\n$ symfony init-opensocial-app <applicationName> <moduleName>");
  }
  
  $applicationName = $args[0];
  $moduleName = $args[1];
  
  // root dir
  $rootDir = sfConfig::get('sf_root_dir');
  // applications dir
  $appsDir = sfConfig::get('sf_app_dir');
  // modules dir
  $modulesDir = sfConfig::get('sf_app_module_dir_name');
  
  // opensocial app dir
  $applicationDir = $appsDir.$applicationName;
  // opensocial app module
  $moduleDir = $applicationDir.DIRECTORY_SEPARATOR.$modulesDir.DIRECTORY_SEPARATOR.$moduleName;
  
  pake_echo_action('plugin-info', "Checking if application '".$applicationDir."' exists...");
  if( !is_dir($applicationDir) )
  {
    pake_echo_action('plugin-action', "Creating application '".$applicationDir."'");
    run_init_app($task, array($applicationName));
  }else
    pake_echo_action('plugin-info', "Application '".$applicationDir."' already exists!");
  
  pake_echo_action('plugin-info', "Checking if module '".$moduleName."' exists...");
  if( !is_dir($moduleDir) )
  {
    pake_echo_action('plugin-action', "Creating module '".$moduleDir."'");
    run_init_module($task, array($applicationName,$moduleName));
  }else
    pake_echo_action('plugin-info', "Module '".$moduleDir."' already exists!");
  
  // getting OpenSocial app dir
  $osAppDirs = loadOpensocialAppDirs($rootDir);
  
  pake_echo_action('plugin-action', "Copying Opensocial application data from '$osAppDirs' to '$applicationDir'");
  os_copy_app_data($osAppDirs,$applicationDir);
  
  // getting OpenSocial app module dir
  $osAppModulesDirs = loadOpensocialAppModuleDirs($rootDir);
  
  pake_echo_action('plugin-action', "Copying Opensocial application module data from  '$osAppDirs' to '$applicationDir'");
  os_copy_app_module_data($osAppModulesDirs,$moduleDir);
  
  // fix action module names
  fixModuleNames($moduleDir,$moduleName);
  
  //enable sample application
  enable_sampleapp($applicationDir,"application");
  
  pake_echo_action('plugin-info', "Congratulations you have successfully created a sample OpenSocial application! \n Please look at README for more information.");
  
}

function os_copy_app_data($osTemplatesDir,$appTemplatesDir)
{
  if(!is_dir($osTemplatesDir))
    throw new Exception("Source dir '$osTemplatesDir' doenst exist!");
  if(!is_dir($appTemplatesDir))
    throw new Exception("Destination dir '$appTemplatesDir' doenst exist!");
    
  pake_echo_action('plugin-info', os_copy_dir($osTemplatesDir,$appTemplatesDir)." application files successfully copied!");    
}

function os_copy_app_module_data($osTemplatesDir,$appTemplatesDir)
{
  if(!is_dir($osTemplatesDir))
    throw new Exception("Source dir '$osTemplatesDir' doenst exist!");
  if(!is_dir($appTemplatesDir))
    throw new Exception("Destination dir '$appTemplatesDir' doenst exist!");
    
  pake_echo_action('plugin-info', os_copy_dir($osTemplatesDir,$appTemplatesDir)." application module files successfully copied!");    
}


/**
 * This code adapted from "sfPakeManagerPluginPlugin"
 *
 * @param unknown_type $srcdir
 * @param unknown_type $dstdir
 * @return unknown
 */
function os_copy_dir($srcdir, $dstdir)
{
  $num = 0;
  
  if( !is_dir($dstdir) )
  {
    mkdir($dstdir);
  }
  
  if( $curdir = opendir($srcdir) )
  {
    while($file = readdir($curdir))
    {
      if( $file != '.' && $file != '..' )
      {
        $srcfile = $srcdir.DIRECTORY_SEPARATOR.$file;
        $dstfile = $dstdir.DIRECTORY_SEPARATOR.$file;
        
        if( is_file($srcfile) )
        {
          if( copy($srcfile, $dstfile) )
          {
            touch($dstfile, filemtime($srcfile));
            $num++;
          }
          
        }
        else if( is_dir($srcfile) )
        {
          $num += os_copy_dir($srcfile, $dstfile);
        }
      }
    }
    
    closedir($curdir);
  }
  
  return $num;
}
?>